﻿
// Transform2DView.cpp: CTransform2DView 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "Transform2D.h"
#endif

#include "Transform2DDoc.h"
#include "Transform2DView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CTransform2DView

IMPLEMENT_DYNCREATE(CTransform2DView, CView)

BEGIN_MESSAGE_MAP(CTransform2DView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
	ON_COMMAND(ID_32771, &CTransform2DView::OnMoveLeft)
	ON_COMMAND(ID_32772, &CTransform2DView::OnMoveRight)
	ON_COMMAND(ID_32773, &CTransform2DView::OnMoveUp)
	ON_COMMAND(ID_32774, &CTransform2DView::OnMoveDown)
	ON_COMMAND(ID_32775, &CTransform2DView::OnScaleUp)
	ON_COMMAND(ID_32776, &CTransform2DView::OnScaleDown)
	ON_COMMAND(ID_32777, &CTransform2DView::OnRotateLeft)
	ON_COMMAND(ID_32778, &CTransform2DView::OnRotationRight)
	ON_COMMAND(ID_32780, &CTransform2DView::OnReflectionOrigin)
	ON_COMMAND(ID_32781, &CTransform2DView::OnRelectionX)
	ON_COMMAND(ID_32782, &CTransform2DView::OnRelectionY)
	ON_COMMAND(ID_32783, &CTransform2DView::OnReflectionYEqualX)
	ON_COMMAND(ID_32784, &CTransform2DView::OnReflectionYEqualNagtX)
	ON_COMMAND(ID_32785, &CTransform2DView::OnShearX)
	ON_COMMAND(ID_32786, &CTransform2DView::OnShearY)
	ON_COMMAND(ID_32787, &CTransform2DView::OnInitRectangle)
END_MESSAGE_MAP()

// CTransform2DView 构造/析构

CTransform2DView::CTransform2DView() noexcept
{
	InitFourPoints();
}

CTransform2DView::~CTransform2DView()
{
}

BOOL CTransform2DView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CTransform2DView 绘图

void CTransform2DView::InitFourPoints()
{
	leftTop.x = -20;
	leftTop.y = 20;

	leftDown.x = -20;
	leftDown.y = -20;

	rightTop.x = 20;
	rightTop.y = 20;

	rightDown.x = 20;
	rightDown.y = -20;
}

void CTransform2DView::DrawCoordinate(CDC* pDC, CRect& rect)
{
	// 画X轴
	pDC->MoveTo(-rect.Width(), 0);
	pDC->LineTo(rect.Width(), 0);

	// 画Y轴
	pDC->MoveTo(0, -rect.Height());
	pDC->LineTo(0, rect.Height());
}

void CTransform2DView::DrawRectangle(CDC* pDC)
{
	CPen pen(PS_SOLID, 3, RGB(0, 0, 0));
	pDC->SelectObject(&pen);

	// 将坐标取整
	leftTop.x = round(leftTop.x);
	leftTop.y = round(leftTop.y);

	rightTop.x = round(rightTop.x);
	rightTop.y = round(rightTop.y);

	leftDown.x = round(leftDown.x);
	leftDown.y = round(leftDown.y);

	rightDown.x = round(rightDown.x);
	rightDown.y = round(rightDown.y);

	// 上边
	pDC->MoveTo(leftTop.x, leftTop.y);
	pDC->LineTo(rightTop.x, rightTop.y);

	// 右边
	pDC->LineTo(rightDown.x, rightDown.y);

	// 下边
	pDC->LineTo(leftDown.x, leftDown.y);

	// 左边
	pDC->LineTo(leftTop.x, leftTop.y);

	DeleteObject(&pen);
}

void CTransform2DView::OnDraw(CDC* pDC)
{
	CTransform2DDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CRect rect;
	GetClientRect(&rect);
	pDC->SetMapMode(MM_ANISOTROPIC);							// 自定义坐标系声明
	pDC->SetWindowExt(rect.Width(), rect.Height());				// 设置坐标系范围
	pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);	// 以客户区中心为原点
	pDC->SetViewportExt(rect.Width(), -rect.Height());			// 设置坐标轴正方向，x轴向右为正，y轴向上为正

	DrawCoordinate(pDC, rect);
	DrawRectangle(pDC);
}


// CTransform2DView 打印

BOOL CTransform2DView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CTransform2DView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CTransform2DView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}


// CTransform2DView 诊断

#ifdef _DEBUG
void CTransform2DView::AssertValid() const
{
	CView::AssertValid();
}

void CTransform2DView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CTransform2DDoc* CTransform2DView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTransform2DDoc)));
	return (CTransform2DDoc*)m_pDocument;
}
#endif //_DEBUG


// CTransform2DView 消息处理程序


void CTransform2DView::OnMoveLeft()
{
	Transformation trans;

	trans.SetTranslationMatrix(-10, 0);
	trans.Translation(leftTop);
	trans.Translation(leftDown);
	trans.Translation(rightTop);
	trans.Translation(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnMoveRight()
{
	Transformation trans;

	trans.SetTranslationMatrix(10, 0);
	trans.Translation(leftTop);
	trans.Translation(leftDown);
	trans.Translation(rightTop);
	trans.Translation(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnMoveUp()
{
	Transformation trans;

	trans.SetTranslationMatrix(0, 10);		
	trans.Translation(leftTop);
	trans.Translation(leftDown);
	trans.Translation(rightTop);
	trans.Translation(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnMoveDown()
{
	Transformation trans;

	trans.SetTranslationMatrix(0, -10);
	trans.Translation(leftTop);
	trans.Translation(leftDown);
	trans.Translation(rightTop);
	trans.Translation(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnScaleUp()
{
	// 以矩形左上角为固定点，获得当前矩形右下角点坐标

	// 计算右下角点变换后的坐标
	Transformation trans;

	trans.Scale(1.25, 1.25, leftTop, leftDown);
	trans.Scale(1.25, 1.25, leftTop, rightTop);
	trans.Scale(1.25, 1.25, leftTop, rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnScaleDown()
{
	// 以矩形左上角为固定点，获得当前矩形右下角点坐标

	// 计算右下角点变换后的坐标
	Transformation trans;
	//trans.SetScaleMatrix(0.8, 0.8);
	trans.Scale(0.8, 0.8, leftTop, leftDown);
	trans.Scale(0.8, 0.8, leftTop, rightTop);
	trans.Scale(0.8, 0.8, leftTop, rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnRotateLeft()
{
	Transformation trans;

	trans.Rotation(25, leftTop, leftDown);		// 逆时针为正
	trans.Rotation(25, leftTop, rightTop);
	trans.Rotation(25, leftTop, rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnRotationRight()
{
	Transformation trans;

	trans.Rotation(-25, leftTop, leftDown);
	trans.Rotation(-25, leftTop, rightTop);
	trans.Rotation(-25, leftTop, rightDown);

	Invalidate(TRUE);
}




void CTransform2DView::OnReflectionOrigin()
{
	Transformation trans;

	trans.ReflectionOrigin(leftTop);
	trans.ReflectionOrigin(leftDown);
	trans.ReflectionOrigin(rightTop);
	trans.ReflectionOrigin(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnRelectionX()
{
	Transformation trans;

	trans.ReflectionX(leftTop);
	trans.ReflectionX(leftDown);
	trans.ReflectionX(rightTop);
	trans.ReflectionX(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnRelectionY()
{
	Transformation trans;

	trans.ReflectionY(leftTop);
	trans.ReflectionY(leftDown);
	trans.ReflectionY(rightTop);
	trans.ReflectionY(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnReflectionYEqualX()
{
	Transformation trans;

	trans.ReflectionYEuqalX(leftTop);
	trans.ReflectionYEuqalX(leftDown);
	trans.ReflectionYEuqalX(rightTop);
	trans.ReflectionYEuqalX(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnReflectionYEqualNagtX()
{
	Transformation trans;

	trans.ReflectionYEuqalNagtX(leftTop);
	trans.ReflectionYEuqalNagtX(leftDown);
	trans.ReflectionYEuqalNagtX(rightTop);
	trans.ReflectionYEuqalNagtX(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnShearX()
{
	Transformation trans;
	
	trans.SetXShearMatrix(2);
	trans.Shear(leftTop);
	trans.Shear(rightTop);

	Invalidate(TRUE);
}


void CTransform2DView::OnShearY()
{
	Transformation trans;

	trans.SetYShearMatrix(1);
	trans.Shear(rightTop);
	trans.Shear(rightDown);

	Invalidate(TRUE);
}


void CTransform2DView::OnInitRectangle()
{
	InitFourPoints();

	Invalidate(TRUE);
}
